package com.situ.supermarket.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

//JDBC工具类
public class DBUtil {
	//数据源 连接池
	private static DataSource ds;
	static {
		try {
			// 获取当前的线程 上下文 类的加载器
			Properties prop = new Properties();
			prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
		    ds =  DruidDataSourceFactory.createDataSource(prop);
		    
		} catch (IOException e) {
			System.out.println("加载DB配置文件失败");
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	//执行DML语句工具方法
	public static int executeDML(String sql,Object...params) {
		Connection conn = null;
		PreparedStatement ps = null;
		try {
			conn = DBUtil.getConnection();
			ps = conn.prepareStatement(sql);
			if(params !=null && params.length>0) {//说明传了参数了，要替换问号
				for(int i=0;i<params.length;i++) {
					ps.setObject(i+1, params[i]);
				}
				
			}
			int i = ps.executeUpdate();
			return i;//影响行数
		}catch (Exception e1) {
			e1.printStackTrace();
		}
		finally {
			DBUtil.close(null, ps, conn);
		}
		return -1;
	}

	public static Long executeCount(String sql,Object...params){
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			conn = getConnection();
			ps = conn.prepareStatement(sql);
			if(params !=null && params.length>0) {//说明传了参数了，要替换问号
				for(int i=0;i<params.length;i++) {
					ps.setObject(i+1, params[i]);
				}
			}
			rs = ps.executeQuery();
			rs.next();
			return rs.getLong(1);
		} catch (Exception e) {

        }finally {
			close(rs, ps, conn);
		}
		return 0L;
    }


	// 封装通用的查询方法，执行DQL语句
	public static <T> List<T> executeDQL(String sql,Class<T> c,Object...params){
		 //创建一个空的集合
		List<T> list = new ArrayList<>();
		Connection conn=null;
		PreparedStatement ps=null;
		ResultSet rs=null;
		try {
			conn=getConnection();
			ps=conn.prepareStatement(sql);
			if(params!=null && params.length>0) {
				for(int i=0;i<params.length;i++) {
					ps.setObject(i+1, params[i]);
				}
			}
			rs=ps.executeQuery();
			
			ResultSetMetaData rsmd = rs.getMetaData();//获取结果集的元数据
			while(rs.next()) {//遍历结果集
				T o=c.newInstance();
				//给成员变量赋值
				//Field[] fs = c.getDeclaredFields();//获取类中所有成员变量
//				for(Field f:fs) {//遍历这个类型里的所有的成员变量
//					f.setAccessible(true);
//					try {
//						
//						//f.getName()	名 转成下划线命名的方式再去取直
//						
//						f.set(o, rs.getObject(f.getName()));
//					} catch (Exception e) {
//						System.out.println(f.getName()+"这一列没赋上值");
//
//					}
//						
//				}
				//找到类中所有的成员变量，对每个成员变量根据名字，去结果集中找到对应的值
				
				//换一种思路：找到所有的查询到结果集数据，根据每一列的名字去类中找
				for(int i=0;i<rsmd.getColumnCount();i++) {//返回结果集有几列,循环这么多次
				    String label = rsmd.getColumnLabel(i+1);//这一列的名字
				    try {
				    	//把label	转成驼峰再去类中找
						 Field f = c.getDeclaredField(StringUtil.change(label));//根据列的名字去找成员变量
						 f.setAccessible(true);
						Object value =  rs.getObject(i+1);
				         f.set(o,value );
				         //System.out.println(label);
					} catch (Exception e) {
						e.printStackTrace();
						System.out.println(label+"这个结果没在类中找到成员变量");
					
					}
				}
				list.add(o);
			}
			
		}catch (Exception e) {
			
		}finally {
			close(rs,ps,conn);
		}
		return list;
	}
    //调用方法返回一个连接对象
	private static Connection getConnection() {
		try {
			return ds.getConnection();
		} catch (Exception e) {
			return null;
		}
	}
    //关闭资源
	private static void close(ResultSet rs, PreparedStatement ps, Connection conn) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}



}